Set DISPLAY in the child process using g_setenv() instead of constructing
authorRoss Burton <ross@openedhand.com>
Wed, 6 Jun 2007 15:57:58 +0000 (15:57 +0000)
committerRoss Burton <rburton@src.gnome.org>
Wed, 6 Jun 2007 15:57:58 +0000 (15:57 +0000)
2007-06-06  Ross Burton  <ross@openedhand.com>

* gdk/x11/gdkspawn-x11.c:
Set DISPLAY in the child process using g_setenv() instead of
constructing a new envp, which lets callers use child setup
functions which call putenv (#442617).

svn path=/trunk/; revision=18062

ChangeLog
gdk/x11/gdkspawn-x11.c

index 5ce6ab34bb1ef371f1288ba56714b31b7aa90424..0f8d4cd36858dcdd9160ccf4e49f1f5efc8fc794 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-06-06  Ross Burton  <ross@openedhand.com>
+
+       * gdk/x11/gdkspawn-x11.c:
+       Set DISPLAY in the child process using g_setenv() instead of
+       constructing a new envp, which lets callers use child setup
+       functions which call putenv (#442617).
+
 2007-06-06  Johan Dahlin  <jdahlin@async.com.br>
 
        reviewed by: Matthias Clasen <mclasen@redhat.com>
index f29021349041d82606a8be42266875219c8bf2da..028351e366288d35359791f66710de8dfe6c4922 100644 (file)
 
 #include <config.h>
 #include <string.h>
-
-#ifdef HAVE_CRT_EXTERNS_H 
-#include <crt_externs.h> /* for _NSGetEnviron */
-#endif
+#include <stdlib.h>
 
 #include "gdkspawn.h"
 
 #include <gdk/gdk.h>
 #include "gdkalias.h"
   
-#ifdef HAVE__NSGETENVIRON
-#define environ (*_NSGetEnviron())
-#else
+typedef struct {
+  char *display;
+  GSpawnChildSetupFunc child_setup;
+  gpointer user_data;
+} UserChildSetup;
 
-/* According to the Single Unix Specification, environ is not in 
- * any system header, although unistd.h often declares it.
+/*
+ * Set the DISPLAY variable, and then call the user-specified child setup
+ * function.  This is required so that applications can use gdk_spawn_* and call
+ * putenv() in their child_setup functions.
  */
-extern char **environ;
-#endif
-
-/**
- * gdk_make_spawn_environment_for_screen:
- * @screen: A #GdkScreen
- * @envp: program environment to copy, or %NULL to use current environment.
- *
- * Returns a modified copy of the program environment @envp (or the current
- * environment if @envp is %NULL) with <envar>DISPLAY</envar> set such that 
- * a launched application (which calls gdk_display_open()) inheriting this 
- * environment would have @screen as its default screen..
- *
- * Returns: a newly-allocated %NULL-terminated array of strings.
- *          Use g_strfreev() to free it.
- *
- * Since: 2.4
- **/
-static gchar **
-gdk_spawn_make_environment_for_screen (GdkScreen  *screen,
-                                      gchar     **envp)
+static void
+set_environment (gpointer user_data)
 {
-  gchar **retval = NULL;
-  gchar  *display_name;
-  gint    display_index = -1;
-  gint    i, env_len;
-
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
-  if (envp == NULL)
-    envp = environ;
-
-  for (env_len = 0; envp[env_len]; env_len++)
-    if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0)
-      display_index = env_len;
-
-  retval = g_new (char *, env_len + 1);
-  retval[env_len] = NULL;
-
-  display_name = gdk_screen_make_display_name (screen);
-
-  for (i = 0; i < env_len; i++)
-    if (i == display_index)
-      retval[i] = g_strconcat ("DISPLAY=", display_name, NULL);
-    else
-      retval[i] = g_strdup (envp[i]);
-
-  g_assert (i == env_len);
-
-  g_free (display_name);
-
-  return retval;
+  UserChildSetup *setup = user_data;
+  
+  g_setenv ("DISPLAY", setup->display, TRUE);
+  
+  setup->child_setup (setup->user_data);
 }
 
 /**
@@ -128,25 +85,22 @@ gdk_spawn_on_screen (GdkScreen             *screen,
                     gint                  *child_pid,
                     GError               **error)
 {
-  gchar    **new_envp;
-  gboolean   retval;
+  UserChildSetup setup_data;
 
   g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
 
-  new_envp = gdk_spawn_make_environment_for_screen (screen, envp);
+  setup_data.display = gdk_screen_make_display_name (screen);
+  setup_data.child_setup = child_setup;
+  setup_data.user_data = user_data;
 
-  retval = g_spawn_async (working_directory,
+  return g_spawn_async (working_directory,
                          argv,
-                         new_envp,
+                         envp,
                          flags,
-                         child_setup,
-                         user_data,
+                         set_environment,
+                         &setup_data,
                          child_pid,
                          error);
-
-  g_strfreev (new_envp);
-
-  return retval;
 }
 
 /**
@@ -194,28 +148,26 @@ gdk_spawn_on_screen_with_pipes (GdkScreen            *screen,
                                gint                 *standard_error,
                                GError              **error)
 {
-  gchar    **new_envp;
-  gboolean   retval;
+  UserChildSetup setup_data;
 
   g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
 
-  new_envp = gdk_spawn_make_environment_for_screen (screen, envp);
+  setup_data.display = gdk_screen_make_display_name (screen);
+  setup_data.child_setup = child_setup;
+  setup_data.user_data = user_data;
 
-  retval = g_spawn_async_with_pipes (working_directory,
+  return g_spawn_async_with_pipes (working_directory,
                                     argv,
-                                    new_envp,
+                                    envp,
                                     flags,
-                                    child_setup,
-                                    user_data,
+                                    set_environment,
+                                    &setup_data,
                                     child_pid,
                                     standard_input,
                                     standard_output,
                                     standard_error,
                                     error);
 
-  g_strfreev (new_envp);
-
-  return retval;
 }
 
 /**